<template>
  <NuxtLayout>
    <div class="con">
      <div class="con_cen">
        <div class="con_cen_left" v-show="pageVisible">
          <ul class="con_cen_left_data">
            <li class="con_cen_left_data_num"><span>已答</span><strong class="success">{{ answerNum }}</strong></li>
            <li class="con_cen_left_data_num"><span>未答</span><strong class="error">{{ notAnswerNum }}</strong></li>
          </ul>
          <div class="con_cen_left_title">
            <el-countdown title="考试结束时间" :value="downTime" />
          </div>
          <div class="con_cen_left_notice">
            <span class="con_cen_left_notice_text">答题卡</span>
          </div>
          <div class="con_cen_left_page">
            <ul class="con_cen_left_page_list">
              <template v-for="(item, index) in listData" :key="index">
                <li class="con_cen_left_page_list_num selected" v-if="item.answer" @click="listIndex = index">{{ index +
                  1 }}</li>
                <li class="con_cen_left_page_list_num active" v-else-if="listIndex == index" @click="listIndex = index">
                  {{ index + 1 }}</li>
                <li class="con_cen_left_page_list_num" @click="listIndex = index" v-else>{{ index + 1 }}</li>
              </template>
            </ul>
            <div class="con_cen_left_page_mask"></div>
          </div>
        </div>
        <div class="con_cen_right" v-show="pageVisible">
          <div class="con_cen_right_label">
            <div class="con_cen_right_label_type">{{ listData[listIndex].type === 0 ? '单选题' : listData[listIndex].type
              === 1 ?
              '多选题' : '判断题' }}</div>
          </div>
          <div class="con_cen_right_item">
            <div class="con_cen_right_item_title" v-show="listData[listIndex].question">{{ listData[listIndex].question
            }}</div>
            <template v-if="listData.imgs && listData.imgs.length > 0">
              <div class="con_cen_right_item_cover" v-for="(item, index) in listData.imgs" :key="index">
                <el-image class="con_cen_right_cover_image" :src="item" :preview-src-list="listData.imgs" v-show="(index + 1) >= listData.imgs.length" />
              </div>
            </template>
            <video class="con_cen_right_item_video" :src="listData.video" controls v-show="listData.video"></video>
            <div class="con_cen_right_imgs" v-if="listData[listIndex].imgs && listData[listIndex].imgs.length > 0">
              <template v-for="(item, index) in listData[listIndex].imgs" :key="index">
                <el-image class="con_cen_right_imgs_cover" :src="item" :preview-src-list="listData.imgs" :initial-index="index" />
              </template>
            </div>
            <!-- 多选题 -->
            <ul class="con_cen_right_options" v-if="listData[listIndex].type == 1">
              <li class="con_cen_right_options_item" v-for="item in listData[listIndex].options" :key="item.letter">
                <el-icon class="con_cen_right_options_item_icon" size="20" color="#00C745" @click="chooseFn(item)"
                  v-if="item.checked">
                  <CircleCheckFilled />
                </el-icon>
                <em class="con_cen_right_options_item_icon round" @click="chooseFn(item)" v-else></em>
                <div class="con_cen_right_options_item_right">
                  <span class="con_cen_right_options_item_right_letter">{{ item.letter }}，</span>
                  <div class="con_cen_right_options_item_right_title" v-html="item.title"></div>
                  <el-image class="con_cen_right_options_item_right_img" :src="item.imgUrl"
                    :preview-src-list="[item.imgUrl]" fit="cover" v-if="item.imgUrl" />
                </div>
              </li>
            </ul>
            <!-- 单选题 判断题 -->
            <ul class="con_cen_right_options" v-else>
              <li class="con_cen_right_options_item" v-for="item in listData[listIndex].options" :key="item.letter">
                <el-icon class="con_cen_right_options_item_icon" size="20" color="#00C745" v-if="item.checked">
                  <CircleCheckFilled />
                </el-icon>
                <em class="con_cen_right_options_item_icon round" @click="chooseFn(item)" v-else></em>
                <div class="con_cen_right_options_item_right">
                  <span class="con_cen_right_options_item_right_letter">{{ item.letter }}，</span>
                  <div class="con_cen_right_options_item_right_title" v-html="item.title"></div>
                  <el-image class="con_cen_right_options_item_right_img" :src="item.imgUrl"
                    :preview-src-list="[item.imgUrl]" fit="cover" v-if="item.imgUrl" />
                </div>
              </li>
            </ul>
            <div class="con_cen_right_page">
              <el-button round @click="pageChangeFn('prev')"
                v-if="listIndex > 0">&nbsp;&nbsp;上一题&nbsp;&nbsp;</el-button>
              <el-button round @click="pageChangeFn('next')"
                v-if="listIndex < (total - 1)">&nbsp;&nbsp;下一题&nbsp;&nbsp;</el-button>
            </div>
            <div class="con_cen_right_sub">
              <el-button type="primary" @click="saveFn">提交试卷</el-button>
            </div>
            <div class="con_cen_right_analysis">
              <div class="con_cen_right_analysis_tips">考试须知</div>
              <div class="con_cen_right_analysis_con">遵守考试规定，在考试期间，考生需要遵守考试规定，不得随意切换屏幕，返回上一级等与考试答题无关操作，如违规者视为考生自愿提前交卷。
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </NuxtLayout>
</template>

<script setup>
import { useCountStore } from '~/store/counter'
import { getExamQuestionApi, submitExamResultApi } from '~/server/api'
import { CircleCheckFilled } from '@element-plus/icons-vue'
useCountStore().$patch({ indexActive: 4 })
definePageMeta({
  validate: async (route) => {
    return /^1\d{5,}$/.test(route.params.id);
  }
})
const prevHost = useRequestHeaders()["x-forwarded-proto"];
const host = useRequestHeaders()["host"];
const fullPath = useRoute()["fullPath"];
const title = ref('模拟考试');
const keywords = ref('模拟考试');
const description = ref('模拟考试');
const subjectId = useRoute().params.id || '';
const downTime = ref(Date.now());
const total = ref(0);
const listData = ref([]);
const listIndex = ref(0);
const answerNum = ref(0);
const notAnswerNum = ref(0);
const saveForm = reactive({
  examSetting: null,
  examSecond: 0,
  subjectId,
  classesId: ''
})
const downInterval = ref(null);
const duration = ref(0);
const pageVisible = ref(false);
// 获取考试数据
async function getExamList() {
  let { data: listRes } = await useAsyncData(() => useServerRequest(getExamQuestionApi, {
    method: 'get',
    params: { subjectId }
  }))
  if (listRes.value && listRes.value.errno === 0 && listRes.value.result) {
    if (listRes.value.result.exerciseList.length < 1) {
      window.location.href = '/exercises';
      ElMessage.warning('未发现考试数据')
      return false
    }
    total.value = listRes.value.result.exerciseList.length;
    listData.value = listRes.value.result.exerciseList;
    duration.value = listRes.value.result.duration;
    listData.value[listIndex.value].options.filter(x => x.checked = false); // 默认值
    downTime.value = Date.now() + (listRes.value.result.duration * 1000); // 倒计时
    calculation()
  }
}
getExamList()
// 上一题 下一题
function pageChangeFn(type) {
  // 上一题
  if (type === 'prev') {
    if (listIndex.value < 1) {
      ElMessage.warning('已是第一题')
      return false;
    }
    listIndex.value--;
  }
  // 下一题
  if (type === 'next') {
    if ((listIndex.value + 1) >= total.value) {
      ElMessage.warning('已是最后一题')
      return false;
    }
    listIndex.value++;
  }
}
// 选择
function chooseFn(val) {
  if (listData.value[listIndex.value].type == 1) { // 多选
    val.checked = !val.checked;
    checkChangeFn()
  } else { // 单选 判断
    listData.value[listIndex.value].options.filter(x => x.checked = false);
    val.checked = true;
    listData.value[listIndex.value].answer = val.letter;
    calculation()
  }
}
// 多选确认
function checkChangeFn() {
  let answerFilter = listData.value[listIndex.value].options && listData.value[listIndex.value].options.length > 0 ? listData.value[listIndex.value].options.filter(x => x.checked) : [];
  let answerMap = answerFilter.map(x => x.letter);
  listData.value[listIndex.value].answer = answerMap.join('');
}
// 已答题 未答题
function calculation() {
  notAnswerNum.value = listData.value.filter(x => !x.answer).length;
  answerNum.value = listData.value.filter(x => x.answer).length;
}
// 提交试卷
function saveFn() {
  ElMessageBox.confirm('请认真审查，是否确认提交试卷？', '系统提示', { showClose: false }).then(async () => {
    save()
  }).catch(() => { })
}
// 交卷
async function save() {
  if (!localStorage.getItem('examAuth')) {
    saveForm.examSetting = { exerciseList: listData.value }; // 考生答题数据赋值
    const loading = ElLoading.service({ text: '提交中...' })
    let res = await useServerRequest(submitExamResultApi, {
      method: 'post',
      body: JSON.stringify(saveForm)
    })
    if (res && res.errno === 0) {
      localStorage.setItem('examAuth', true)
      ElMessage.success('提交成功')
      window.location.href = '/exercises'
      return false
    }
    loading.close()
  }
}
// 刷新键
const disableF5 = (event) => {
  if ((event.ctrlKey || event.metaKey) && event.key === 'F5' || event.key === 'F5' || (event.ctrlKey || event.metaKey) && (event.key === 'r' || event.key === 'R')) {
    event.preventDefault();
    ElMessageBox.confirm('是否确认刷新，视为考生自愿交卷', '系统提示', { showClose: false }).then(() => {
      save()
    }).catch(() => { })
  }
};
// 浏览器刷新
const unloadFn = (event) => {
  pageVisible.value = false;
  save()
  event.stopPropagation()
}
// 窗口变化
const windowFn = (event) => {
  if (document.visibilityState === 'hidden') {
    event.stopPropagation();
    pageVisible.value = false;
    save()
  }
}
// 回退
const handlePopState = (event) => {
  // 清除缓存
  if (localStorage.getItem('examId')) {
    localStorage.removeItem('examId')
  }
  save()
}
// 挂载前
onBeforeMount(() => {
  // 不存在或者不等于进入前保存的id
  if (!localStorage.getItem('examId') || localStorage.getItem('examId') != subjectId) {
    window.location.href = '/exercises';
  } else {
    pageVisible.value = true;
    // 用时
    downInterval.value = setInterval(() => {
      saveForm.examSecond += 1;
      if (saveForm.examSecond >= duration.value) {
        clearInterval(downInterval.value)
        downInterval.value = null;
        save()
        return false
      }
    }, 1000)
  }
})
// 挂载后
onMounted(() => {
  // 缓存存在跳回题库列表
  if (localStorage.getItem('examAuth')) {
    window.location.href = '/exercises';
    return false
  }
  // 页面刷新
  window.addEventListener('keydown', disableF5)
  window.addEventListener('beforeunload', unloadFn)
  window.addEventListener('visibilitychange', windowFn)
  window.history.pushState(null, null, '')
  window.addEventListener('popstate', handlePopState);
})
// 改变后
onUpdated(() => {
  // 缓存存在跳回题库列表
  if (localStorage.getItem('examAuth')) {
    window.location.href = '/exercises';
    return false
  }
})
// 卸载前
onBeforeUnmount(() => {
  // 清除计时器
  clearInterval(downInterval.value)
  downInterval.value = null;
  window.removeEventListener('keydown')
  window.removeEventListener('beforeunload')
  window.removeEventListener('visibilitychange')
})
// 卸载后
onUnmounted(() => {
  window.removeEventListener('popstate', handlePopState);
})
// TDK
useSeoMeta({
  title,
  keywords,
  description,
  ogTitle: title,
  ogDescription: description,
  ogType: "article",
  ogUrl: `${prevHost}://${host}${fullPath}`,
})
</script>

<style lang="less" scoped>
* {
  user-select: none;
}

.con {
  min-height: calc(100vh - 454px);
  box-sizing: border-box;
  padding: 20px 0;

  &_cen {
    width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: flex-start;

    &_left {
      width: 300px;
      height: 459px;
      background: #fff url('https://static.dzyxzx.cn/jkbpc/practice_card_back.png') top left / 100% no-repeat;
      border-radius: 10px;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.03);
      margin-right: 20px;
      overflow: hidden;

      &_data {
        padding-top: 33px;
        display: flex;
        align-items: baseline;
        justify-content: space-around;

        &_num {
          font-size: 18px;
          display: flex;
          align-items: center;

          >strong {
            font-size: 26px;
            margin-left: 8px;
            line-height: 24px;

            &.success {
              color: #00C745;
            }

            &.error {
              color: #FF3F29;
            }
          }
        }
      }

      &_title {
        font-weight: bold;
        font-size: 24px;
        text-align: center;
        padding-top: 33px;
        line-height: 36px;
      }

      &_notice {
        margin-top: 40px;
        display: flex;
        align-items: center;
        justify-content: center;

        &_text {
          font-size: 14px;
          color: #666666;
          margin-left: 7px;
          line-height: 20px;
        }
      }

      &_page {
        height: calc(100% - 235px);
        margin-top: 25px;
        position: relative;

        &_list {
          height: 100%;
          overflow-y: auto;
          padding-right: 15px;
          padding-bottom: 15px;
          padding-left: 10px;

          &_num {
            width: 35px;
            height: 35px;
            line-height: 33px;
            border-radius: 35px;
            text-align: center;
            overflow: hidden;
            font-size: 13px;
            box-sizing: border-box;
            border: 1px solid #ccc;
            color: #ccc;
            cursor: pointer;
            margin: 0 0 15px 15px;
            float: left;

            &:hover,
            &.active {
              border-color: #409eff;
              color: #409eff;
            }

            &.selected {
              background-color: #409eff !important;
              border-color: #409eff !important;
              color: #fff !important;
            }
          }
        }

        &_mask {
          position: absolute;
          right: 17px;
          bottom: 0;
          left: 0;
          z-index: 1;
          height: 30px;
          background: linear-gradient(transparent, #fff);
        }
      }
    }

    &_right {
      flex: 1;
      min-height: 459px;
      background-color: #fff;
      border-radius: 10px;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.03);
      padding: 30px;
      box-sizing: border-box;
      display: flex;
      align-items: flex-start;

      &_label {
        white-space: nowrap;

        &_type {
          margin: 9px 12px 0 0;
          height: 20px;
          line-height: 20px;
          padding: 0 5px;
          border-radius: 5px;
          background-color: #E3F0FF;
          color: #64A0E6;
          font-size: 14px;
        }
      }

      &_item {
        flex: 1;

        &_title {
          line-height: 36px;
          font-size: 18px;
          display: flex;
          flex-wrap: wrap;
          margin-bottom: 12px;
        }

        &_cover {
          margin-bottom: 12px;

          &_image {
            max-width: 100%;
            cursor: pointer;
          }
        }

        &_video {
          max-width: 100%;
          height: 300px;
          margin-bottom: 12px;
          display: block;
        }
      }

      &_options {
        // margin-top: 12px;
        // padding-left: 64px;

        &_item {
          display: flex;
          align-content: flex-start;

          &_icon {
            margin: 9px 14px 0 0;
            cursor: pointer;

            &.round {
              width: 20px;
              height: 20px;
              display: flex;
              align-items: center;
              justify-content: center;

              &::after {
                content: '';
                border: 1px solid #ccc;
                width: 17.5px;
                height: 17.5px;
                border-radius: 50%;
                box-sizing: border-box;
                display: block;
              }
            }

            &.selected {
              cursor: auto;
            }
          }

          &_right {
            flex: 1;
            display: flex;

            &_letter {
              line-height: 36px;
              font-size: 18px;
            }

            &_title {
              line-height: 36px;
              font-size: 18px;
              display: flex;
              flex-wrap: wrap;
            }

            &_img {
              height: 36px;
              margin-left: 10px;
            }
          }
        }
      }

      &_page {
        margin-top: 20px;
        // padding-left: 64px;
      }

      &_analysis {
        margin-top: 70px;

        &_tips {
          font-weight: bold;
          font-size: 18px;
        }

        &_con {
          margin-top: 15px;
          line-height: 24px;
          color: #666;
          font-size: 14px;
        }
      }

      &_sub {
        margin-top: 50px;
        text-align: center;
      }
    }
  }
}
</style>